再來,進入學習的第二個重點部分-
嘗試利用正規表達式來篩選資料
在此之前,先將前置作業完成
1.先抓出需要設置監聽器與更改的元素區塊
const searchInput = document.querySelector(".search");
const suggestions = document.querySelector(".suggestions");
2.對searchInput設置監聽器
searchInput.addEventListener("change", '先留空');
searchInput.addEventListener("keyup", '先留空');
3.製作需要的函式
第一步:依據searchInput 輸入的條件,篩選出符合的資料
function findMatches(wordToMatch, cities) {
return cities.filter((place) => {
const regex = new RegExp(wordToMatch, "gi");
return place.city.match(regex) || place.state.match(regex);
});
}
這裡用到了之前練習的filter()
來過濾cities這筆陣列,我們需要給filter篩選的條件
正規表達式出場
因為是需要更動的變數,所以需要使用建構子函式帶入匹配的字串
對正規表達式有興趣可以稍微看看這篇。
[JS] 正則表達式(Regular Expression, regex)
const regex = new RegExp(wordToMatch, "gi");
/.../g: global 的意思,找到之後會繼續往後配對
/.../i: case insensitive 的意思,不論大小寫都接受
定義出要匹配的條件後,在filter內遍歷cities中的每一個物件中,
city與state的值,若符合正規表達式定義的條件,就回傳為一個新的陣列。
第二步:將符合的資料用JS寫入Html
先設定好一個簡單的函式內容,並確定監聽器可以觸發這個函式
function displayMatches() {
console.log(this.value)
}
監聽器綁上函式
searchInput.addEventListener('change', displayMatches);
searchInput.addEventListener('keyup', displayMatches);
當searchInput有發生change或者keyup事件,
都會觸發displayMatches這個函式,也因此,我們可以得到使用者在輸入的條件。
於是就可以套用剛剛做好的findMatches()函式,得到篩選好的陣列
function displayMatches() {
const matchArray = findMatches(this.value, cities);
console.log(matchArray)
}
接下來就是將過濾好的陣列拆解後,放入html中
function displayMatches() {
const matchArray = findMatches(this.value, cities);
const html = matchArray.map((place) => {
return `
<li>
<span class="name">${place.city},${place.state}</span>
<span class="population">${place.population}</span>
</li>
`
})
console.log(html)
}
印出目前的html,發現還是陣列的形式,在這裡就利用join()
將陣列轉成字串,並把做好的html,放進suggestions區塊中。
function displayMatches() {
const matchArray = findMatches(this.value, cities);
const html = matchArray.map((place) => {
return `
<li>
<span class="name">${place.city},${place.state}</span>
<span class="population">${place.population}</span>
</li>
`
}).join('')
suggestions.innerHTML = html
}
基本上已經完成90%了,但還要做得更細緻一點。
1.符合查詢條件的字都要加上黃色的背景色
正規表達式又有第二招可以用了,
這招是要用正規表達式挑出需要替換成有背景色的字元
function displayMatches() {
const matchArray = findMatches(this.value, cities);
const html = matchArray.map((place) => {
const regex = new RegExp(this.value, 'gi');
const cityName = place.city.replace(regex, `<span class="hl">${this.value}</span>`)
const stateName = place.state.replace(regex, `<span class="hl">${this.value}</span>`);
return `
<li>
<span class="name">${cityName},${stateName}</span>
<span class="population">${place.population}</span>
</li>
`
}).join('');
suggestions.innerHTML = html;
}
2.population(人口數)要3位數一個逗點
先設定將數字轉換3位數一個逗點的函式,再將人口數丟入這個函式中
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
function displayMatches() {
...
return `
<li>
<span class="name">${cityName},${stateName}</span>
<span class="population">${numberWithCommas(place.population)}</span>
</li>
`
}).join('');
suggestions.innerHTML = html;
}
今天的練習完成囉,完整的程式碼請直接點擊下方codePen連結
codePen
或者也可以直接到WES BOS的網站下載打包好的檔案
javascript30